#include "BCSAMA.h"

//************************************
// Method:    	BCSAMA_PACK_Make			打包程序
// Programmer:  lww
// Time:		2019/2/16
// Returns:   	int							打包字节数
// Parameter: 	void * Data					数据区头指针
// Parameter: 	short Head					报头
// Parameter: 	short Tail					报尾
// Parameter: 	int Limit_Len				单次数据包长度限制
// Parameter: 	short * SaveModel_Num		存储的模块数量
//************************************
int BCSAMA_PACK_Make(void* Data, short Head, short Tail, int Limit_Len, short* SaveModel_Num)
{
#define MEMWRITE1(name)	MEMWRITE(name, Data);
	int _iLen = 0;
	short tmp_short;
	static int i = 0;
	void* Data1 = NULL;
	int Model_ID, Model_Type;

	//< 报头
	MEMWRITE1(Head);

	//< 站号
	tmp_short = Station_ID;
	MEMWRITE1(tmp_short);

	//< 第三个数据存放从下一个数据开始从后数多少个字节为报尾，用于对报文的报尾进行校验，此处先保留该存储位置，稍后再对其进行存储
	Data1 = Data;
	tmp_short = 0;
	MEMWRITE1(tmp_short);
	_iLen = (int)(_iLen - sizeof(tmp_short));

	//< 第四个数据存储本次要广播的模块数量，这个数据等打包完成后最后写入，此处先保留该存储位置，稍后再对其进行存储
	MEMWRITE1(SaveModel_Num[0]);
	_iLen =(int)( _iLen - sizeof(SaveModel_Num[0]));

	for (; i < Model_TotalNum; )
	{
		Model_ID = Model_Calcu_ID[i];
		Model_Type = Model_Calcu_Type[i];
		_iLen += BCSAMA(&Model_List[Model_Type], Model_ID, &Data, SaveModel_Num);

		i++;
		if (_iLen >= Limit_Len)
			break;
	}
	if (i >= Model_TotalNum)
		i = 0;

	//< 写第三个数据
	tmp_short = (short)(_iLen - sizeof(Head) - sizeof(short) + sizeof(SaveModel_Num[0]));//< 等于目前已经计数的长度减去报头，减去站号，加上要广播模块数量数据的长度
	MEMWRITE(tmp_short, Data1);

	//< 写第四个数据
	MEMWRITE(SaveModel_Num[0], Data1);

	//< 报尾
	MEMWRITE1(Tail);
	return _iLen;
}


//************************************
// Method:    	tBCSAMA				广播SAMA线程
// Programmer:  lww
// Time:		2019/1/2
// Returns:   	void *
// Parameter: 	void * arg
//************************************
void *tBCSAMA(void* arg)
{
#define PACK_MAXNUM	2048
#define LIMIT_LEN	512
	int sock;
	struct sockaddr_in NetA;
	struct sockaddr_in NetB;
	timer_t BCSAMA_Timer;
	struct timespec time;
	short Head = 7656;				//< 报头
	short Tail = 1214;				//< 报尾
	char Data2Send[PACK_MAXNUM];	//< 存放数据包的数组
	int _iLen = 0;
	short SaveModel_Num = 0;		//< 当前数据包广播的模块数量

	printf("the Kernel_%s is %d\r\n", "tBCSAMA_ID", syscall(SYS_gettid));			//< duan20200610
	//< 初始化UDP设置
	if (false == UDP_Init(&sock, BCSAMA_PORT, 0, 0, UDP_SEND_STATUS, nullptr)) { return 0; }

	//< 设置发送到的IP地址及端口
	Addr_Set(&NetA, BCSAMA_PORT, inet_addr(NETA_IP_BC));
	Addr_Set(&NetB, BCSAMA_PORT, inet_addr(NETB_IP_BC));

	//< 设置广播周期
	MS2TimeSpec(&time, BCSAMA_PERIOD);

	//< 开启定时中断
	Timer_Create(&BCSAMA_Timer, BcSamaSIG, &time);
	while (1)
	{
		//< 等待信号量释放进行广播操作
		/*MUTEX_LOCK(BcSama_Mutex, "BcSama_Mutex lock failed");*/
		SEM_WAIT(BcSamaSemId, "BcSamaSemId wait failed");

		SaveModel_Num = 0;

		if (SYS_Role == Master_Alone_Role || SYS_Role == Master_Twins_Role)
		{
			//< 数据打包
			memset(Data2Send, 0, sizeof(Data2Send));
			_iLen = BCSAMA_PACK_Make(Data2Send, Head, Tail, LIMIT_LEN, &SaveModel_Num);

			if (SaveModel_Num > 0)
			{
				//< 发送数据
				UDP_Send(&sock, &NetA, (char*)Data2Send, _iLen);
				UDP_Send(&sock, &NetB, (char*)Data2Send, _iLen);
			}
		}
	}
	close(sock);//< 断开连接
#undef LIMIT_LEN
#undef PACK_MAXNUM
}
